package com.ruslan.magaz.service;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ruslan.magaz.domain.Cart;
import com.ruslan.magaz.domain.Category;
import com.ruslan.magaz.domain.Order;
import com.ruslan.magaz.domain.OrderedItem;
import com.ruslan.magaz.domain.Product;
import com.ruslan.magaz.domain.Rating;
import com.ruslan.magaz.domain.User;
import com.ruslan.magaz.repository.ItemDao;

@Service
public class ItemServiceImpl implements ItemService{

	@Autowired
	private ItemDao itemDao;
	
	@Override
	@Transactional
	public boolean updateCart(Cart cart) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	@Transactional
	public Product getProductById(int id) {
		return itemDao.getProductById(id);
	}

	@Override
	@Transactional
	public List<Category> getAllCategories() {
		return itemDao.getAllCategories();
	}

	@Override
	@Transactional
	public List<Product> getAllProductsForCategory(int categoryId, int pageNum, int pageSize) {
		return itemDao.getAllProductsForCategory(categoryId, pageNum, pageSize);
	}
	
	@Override
	@Transactional
	public int productsForCategoryPageCount(int categoryId, int pageSize) {
		return itemDao.productsForCategoryPageCount(categoryId, pageSize);
	}
	
	@Override
	@Transactional
	public double getAvgRating(int productId) {
		return itemDao.getAvgRating(productId);
	}
	
	@Override
	@Transactional
	public int countRaters(int productId) {
		return itemDao.countRaters(productId);
	}
	
	@Override
	@Transactional
	public List<OrderedItem> getOrderedItemsFromCart(Order order, Map<Integer, Integer> productMap) {
		List<OrderedItem> orderedItems = new ArrayList<OrderedItem>();
		for (Map.Entry<Integer, Integer> entry : productMap.entrySet()){
			OrderedItem orderedItem = new OrderedItem();
			orderedItem.setOrder(order);
			Product product =  getProductById(entry.getKey());
			orderedItem.setProduct(product);
			orderedItem.setProductPrice(product.getActualPrice());
			orderedItem.setProductQuantity(entry.getValue());
			orderedItems.add(orderedItem);
		}
		return orderedItems;
	}

	@Override
	@Transactional
	public Rating getRatingForUserNItem(int userId, int itemId) {
		return itemDao.getRatingForUserNItem(userId, itemId);
	}

	@Override
	@Transactional
	public void addRating(Rating rating) {
		itemDao.addRating(rating);	
	}
	
	
	@Override
	@Transactional
	public void editRating(Rating rating) {
		itemDao.editRating(rating);
		
	}


	@Override
	public Map<Integer, Integer> getCartFromOrder(Order order) {
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
   	 	for (OrderedItem orderedItem: order.getOrderedItems()){
   	 		map.put(orderedItem.getProduct().getProductId(), orderedItem.getProductQuantity());
   	 	}
   	 	return map;
   	 	
	}

	@Override
	public Set<Rating> sortRatings(Collection<Rating> ratings) {
		Set<Rating> newRatings = new TreeSet<Rating>(new Comparator<Rating>(){
			@Override
			public int compare(Rating o1, Rating o2) {
				if (o1.getReviewDate() == null){
					return 1;
				}
				if (o2.getReviewDate() == null){
					return -1;
				}
				if(o1.getReviewDate().after(o2.getReviewDate())){
					return -1;
				}else{
					return 1;
				}
			}
		});
		newRatings.addAll(ratings);
		return newRatings;
	}

	@Override
	@Transactional
	public List<Rating> getAllReviewsForProduct(int productId, int pageNum, int pageSize) {
		return itemDao.getAllReviewsForProduct(productId, pageNum, pageSize);
	}

	@Override
	@Transactional
	public int reviewsForProductPageCount(int productId, int pageSize) {
		return itemDao.reviewsForProductPageCount(productId, pageSize);
	}

	@Override
	@Transactional
	public int getCountForProductId(int productId) {
		return itemDao.getCountForProductId(productId);
	}

	@Override
	@Transactional
	public List<Category> getAllCategories(int pageNum, int pageSize) {
		return itemDao.getAllCategories(pageNum, pageSize);
	}

	@Override
	@Transactional
	public int categoriesPageCount(int pageSize) {
		return itemDao.categoriesPageCount(pageSize);
	}

	@Override
	@Transactional
	public void moveProductsFromCategory(int fromId, int toId) {
		itemDao.moveProductsFromCategory(fromId, toId);
	}

	@Override
	@Transactional
	public int countItemsInCategory(int categoryId) {
		return itemDao.countItemsInCategory(categoryId);
	}

	@Override
	@Transactional
	public void addCategory(Category category) {
		itemDao.addCategory(category);
	}

	@Override
	@Transactional
	public void removeCategory(int categoryId) {
		itemDao.removeCategory(categoryId);
	}

	@Override
	@Transactional
	public Category getCategoryByName(String name) {
		return itemDao.getCategoryByName(name);
	}

	@Override
	@Transactional
	public void editProduct(Product product) {
		itemDao.editProduct(product);
		
	}

	@Override
	@Transactional
	public void deepEditProduct(Product product) {
		itemDao.deepEditProduct(product);
		
	}

	@Override
	@Transactional
	public void addProduct(Product product) {
		itemDao.addProduct(product);
		
	}

	@Override
	@Transactional
	public void editCategory(Category category) {
		itemDao.editCategory(category);
		
	}

	@Override
	@Transactional
	public Category getCategoryById(int categoryId) {
		return itemDao.getCategoryById(categoryId);
	}

	@Override
	@Transactional
	public Integer getFirstCategoryId() {
		return itemDao.getFirstCategoryId();
	}

	@Override
	@Transactional
	public List<String> getCategoryNames() {
		return itemDao.getCategoryNames();
	}
}
